home *** CD-ROM | disk | FTP | other *** search
-
- #include "AppleShareFileServerControl.h"
-
- #include <Errors.h>
- #include <LowMem.h>
- #include <Processes.h>
- #include <Sound.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
-
- // ---------------------------------------------------------------------------------------
- // (Summary sample for "Starting and Stopping the File Server")
-
- OSErr
- StartStopServer (Boolean startIt, SInt16 howLong);
- OSErr
- GetServerState (UInt16* state);
- OSErr
- ShutDownServer (SInt16 howLong);
- OSErr
- CancelShutDown (void);
- OSErr
- StartServer (void);
-
- // Sample 1a:
- // StartStopServer shows you how to start or stop the AppleShare File Server based on
- // what state it's currently in...
-
- enum {
- kRunningNormally,
- kRunningButShuttingDown,
- kNotRunning
- };
-
- OSErr
- StartStopServer (Boolean startIt, SInt16 howLong) {
-
- OSErr err = noErr;
- UInt16 serverState;
-
- // In order to figure out what to send the server, we need to know what state it's in,
- // and then make the appropriate judgement...
-
- err = GetServerState (&serverState);
- if (err == noErr) {
- if (startIt) {
- if (serverState == kRunningNormally) {
- // We're already running--do nothing...
- } else if (serverState == kRunningButShuttingDown) {
- err = CancelShutDown ();
- } else {
- err = StartServer ();
- } // if
- } else {
- if (serverState != kRunningNormally) {
- // We're either not running or will soon be not running--do nothing...
- } else {
- err = ShutDownServer (howLong);
- } // if
- } // if
- } // if
-
- return err;
-
- } // StartStopServer
-
- // Sample 1b:
- // GetServerState determines whether the server is running or not...
-
- OSErr
- GetServerState (UInt16* state) {
-
- OSErr err = noErr;
- SCParamBlockRec serverControl;
- PollServerParamPtr pollParam = &serverControl.pollServerParam;
-
- pollParam->scCode = kSCPollServer;
- pollParam->scSecondsLeft = 0; // For MFS compatibility...
- err = ServerDispatchSync (&serverControl);
- if (pollParam->scServerState == kSCPollRunning) {
- if (pollParam->scDisconnectState == kSCNotDisconnecting) {
- *state = kRunningNormally;
- } else {
- *state = kRunningButShuttingDown;
- } // if
- } else if (pollParam->scServerState == kSCPollStartingUp) {
- *state = kRunningNormally; // will soon be up...
- } else {
- *state = kNotRunning;
- } // if
-
- return err;
-
- } // GetServerState
-
- // Sample 1c:
- // StartServer starts the server...
-
- OSErr
- StartServer (void) {
-
- OSErr err = noErr;
- SCParamBlockRec serverControl;
- StartParamPtr startParam = &serverControl.startParam;
-
- startParam->scCode = kSCStartServer;
- startParam->scStartSelect = kSCCurrentlyInstalled;
- startParam->scEventSelect = kSCUseFinderExtension;
- err = ServerDispatchSync (&serverControl);
-
- return err;
-
- } // StartServer
-
- // Sample 1d:
- // ShutDownServer causes the server to shutdown after a specified time...
-
- OSErr
- ShutDownServer (SInt16 howLong) {
-
- OSErr err = noErr;
- SCParamBlockRec serverControl;
- DisconnectParamPtr shutDownParam = &serverControl.disconnectParam;
-
- shutDownParam->scCode = kSCShutDown;
- shutDownParam->scNumMinutes = howLong;
- shutDownParam->scFlags = 0;
- shutDownParam->scMessagePtr = "\pServer is Shutting Down!";
-
- err = ServerDispatchSync (&serverControl);
-
- return err;
-
- } // ShutDownServer
-
- // Sample 1e:
- // CancelShutDown aborts the server's shutdown sequence...
-
- OSErr
- CancelShutDown (void) {
-
- OSErr err = noErr;
- SCParamBlockRec serverControl;
- DisconnectParamPtr disconnectParam = &serverControl.disconnectParam;
-
- disconnectParam->scCode = kSCCancelShutDown;
-
- err = ServerDispatchSync (&serverControl);
-
- return err;
-
- } // CancelShutDown
-
-
- // ---------------------------------------------------------------------------------------
-
- // (Summary sample for "SCGetExpFldr")
-
- OSErr
- GetSharedVolumeInfo (SInt16 vRefNum[], SInt32 dirID[], SInt16 logins[], UInt16 arraySize);
- OSErr
- GetMinMaxIndexBounds (SInt16* minIndex, SInt16* maxIndex);
-
- // Sample 2a:
- // GetSharedVolumeInfo returns information about mounted volumes...
-
- OSErr
- GetSharedVolumeInfo (SInt16 vRefNum[], SInt32 dirID[], SInt16 logins[], UInt16 arraySize) {
-
- OSErr err = noErr;
- UInt16 arrayUsed = 0;
- SInt16 curIndex, minIndex, maxIndex;
- SCParamBlockRec serverControl;
- StandardParamPtr standardParam = &serverControl.standardParam;
-
- // Before we begin, we need to determine what the minimum and maximum
- // index values for SCGetExpFldr are...
-
- err = GetMinMaxIndexBounds (&minIndex, &maxIndex);
- if (err == noErr) {
- curIndex = minIndex;
- standardParam->scCode = kSCGetExpFldr;
- standardParam->scNamePtr = NULL; // We'll ignore the names...
- while ((arrayUsed < arraySize) && (curIndex <= maxIndex)) {
- err = ServerDispatchSync (&serverControl);
- if (err == noErr) {
- vRefNum[arrayUsed] = standardParam->scVRefNum;
- dirID[arrayUsed] = standardParam->scDirID;
- logins[arrayUsed] = standardParam->scLogins;
- arrayUsed += 1;
- } // if
- curIndex += 1;
- if (err == fnfErr) {
- err = noErr; // Just means the position was empty
- } // if
- if (err != noErr) {
- break;
- } // if
- } // while
- } // if
-
- return err;
-
- } // GetSharedVolumeInfo
-
- // Sample 2b:
- // GetMinMaxIndexBounds returns the range of indicies that will be valid...
-
- OSErr
- GetMinMaxIndexBounds (SInt16* minIndex, SInt16* maxIndex) {
-
- OSErr err = noErr;
- SCParamBlockRec serverControl;
- SetupInfoRec setupInfo;
- SetupParamPtr setupParam = &serverControl.setupParam;
-
- setupParam->scCode = kSCGetSetupInfo;
- setupParam->scSetupPtr = &setupInfo;
-
- err = ServerDispatchSync (&serverControl);
- *minIndex = -setupParam->scMaxVolumes; // Volumes are always negative...
- *maxIndex = setupParam->scMaxExpFolders;
-
- return err;
-
- } // GetMinMaxIndexBounds
-
- // ---------------------------------------------------------------------------------------
- // (Summary Sample for "Sending Messages to Users")
-
- OSErr
- SendGreetingToAll (void);
- OSErr
- GetNumberOfUsers (SInt32* numUsers);
- OSErr
- GetUser (SInt32 index, StringPtr name, SInt32* userID);
- OSErr
- SendUserMessage (SInt32 userID, StringPtr name);
-
- // Sample 3a:
- // SendGreetingToAll sends the specified text message to every user...
- OSErr
- SendGreetingToAll (void) {
-
- OSErr err = noErr;
- SInt32 userIndex, numUsers;
- SInt32 userID;
- Str255 userName;
-
- // We could send a message to all users at once, but we'll do it one at a time so
- // that we can customize the message a little bit!
-
- err = GetNumberOfUsers (&numUsers);
- if (err == noErr) {
- userIndex = 0;
- while (userIndex <= numUsers) {
- err = GetUser (userIndex, userName, &userID);
- if (err == noErr) {
- err = SendUserMessage (userID, userName);
- } else if (err == fnfErr) {
- err = noErr; // User does not exist at this session ID...
- } // if
- if (err != noErr) {
- break;
- } // if
- userIndex += 1;
- } // while
- } // if
-
- return err;
-
- } // SendGreetingToAll
-
- // Sample 3b:
- // GetNumberOfUsers returns the number of users on the system...
- OSErr
- GetNumberOfUsers (SInt32* numUsers) {
-
- OSErr err = noErr;
- SCParamBlockRec serverControl;
- SetupInfoRec setupInfo;
- SetupParamPtr setupParam = &serverControl.setupParam;
-
- setupParam->scCode = kSCGetSetupInfo;
- setupParam->scSetupPtr = &setupInfo;
-
- err = ServerDispatchSync (&serverControl);
- *numUsers = setupParam->scCurMaxSessions;
-
- return err;
-
- } // GetNumberOfUsers
-
- // Sample 3c:
- // GetUser takes an index, and returns a user name and ID...
- OSErr
- GetUser (SInt32 index, StringPtr name, SInt32* userID){
-
- OSErr err = noErr;
- SCParamBlockRec serverControl;
- UserInfoParamPtr userInfoParam = &serverControl.userInfoParam;
-
- userInfoParam->scCode = kSCGetUserNameRec;
- userInfoParam->scNamePtr = name;
- userInfoParam->scPosition = index;
-
- err = ServerDispatchSync (&serverControl);
- *userID = userInfoParam->scUNRecID;
-
- return err;
-
- } // GetUser
-
- // Sample 3d:
- // SendUser message send the user a personalized message...
- OSErr
- SendUserMessage (SInt32 userID, StringPtr name) {
-
- OSErr err = noErr;
- SCParamBlockRec serverControl;
- DisconnectParamPtr messageParam = &serverControl.disconnectParam;
- Str255 message = "\pHello ";
-
- messageParam->scCode = kSCSendMessage;
- messageParam->scDiscArrayPtr = &userID; // an array of 1
- messageParam->scArrayCount = 1;
- messageParam->scFlags = 0;
- BlockMoveData (name, &message[StrLength(message) + 1], StrLength (name));
- messageParam->scMessagePtr = message;
-
- err = ServerDispatchSync (&serverControl);
-
- return err;
-
- } // SendUserMessage
-
- // ---------------------------------------------------------------------------------------
- // (Summary Sample for "Using Server Event Handlers")
-
- OSErr
- InstallOrRemoveEventHandler (ServerEventQEntryPtr seqEntry, Boolean install);
-
- // Sample 4:
- // InstallRemoveEventHandler installs or removes an event handler queue entry from the
- // server...
-
- OSErr
- InstallOrRemoveEventHandler (ServerEventQEntryPtr seqEntry, Boolean install) {
-
- OSErr err = noErr;
- SCParamBlockRec serverControl;
- ServerEventParamPtr serverEventParam = &serverControl.serverEventParam;
-
- if (install) {
- serverEventParam->scCode = kSCInstallServerEventProc;
- } else {
- serverEventParam->scCode = kSCRemoveServerEventProc;
- } // if
- serverEventParam->scSEQEntryPtr = seqEntry;
-
- err = ServerDispatchSync (&serverControl);
-
- return err;
-
- } // InstallOrRemoveEventHandler
-
- // ---------------------------------------------------------------------------------------
- // (Summary Sample for "Sample Server Event Handler Code")
-
- // Sample 5a:
- // We will queue events and process them in the main event loop. We need to add some
- // structure to the standard data types...
-
- // For convenience, add some fields on the front of a ServerEventRecord so that we can
- // use OS Queue manipulation routines on them...
- typedef struct {
- QElemPtr qLink; // Make OS queue-compatible...
- SInt16 qType;
- ExtendedServerEventRecord eventRec;
- } OurServerEventRecord;
-
- // Similarly, we can add some fields after the ServerEventQEntry so that we have
- // access to them in our event handler...
- typedef struct {
- ServerEventQEntry queueEntry; // actual queue entry...
- QHdr freeQ; // list of free OurServerEventRecord
- QHdr usedQ; // list of used OurServerEventRecord
- } OurServerEventQEntry;
-
- // (Prototypes for completeness only)...
-
- OSErr
- InitServerEventQueueData (OurServerEventQEntry* eventQueueEntry, OurServerEventRecord toQueue[],
- UInt32 numEventRecords);
- pascal void
- ServerEventHandler (OurServerEventQEntry* mainEntry, ExtendedServerEventRecord* event);
- void
- SetEventFlag (OurServerEventQEntry* mainEntry, UInt32 whichEvent, Boolean onOff);
- void
- SetControlFlag (OurServerEventQEntry* mainEntry, UInt32 whichEvent, Boolean onOff);
- void
- SetAFPFlag (OurServerEventQEntry* mainEntry, UInt32 whichEvent, Boolean inDo,
- Boolean inReply, Boolean onOff);
- void
- ProcessQueuedEvents (OurServerEventQEntry* mainEntry);
-
- // Sample 5b:
- // InitServerEventQueue creates a custom queue entry containing everything we need to
- // go ahead and start receiving events...
-
- OSErr
- InitServerEventQueueData (OurServerEventQEntry* eventQueueEntry, OurServerEventRecord toQueue[],
- UInt32 numEventRecords) {
-
- OSErr err = noErr;
- QHdr emptyQueueInit = { 0, NULL, NULL };
- static ServerEventHandlerUPP ourCallBack = NULL;
-
- // Create the callback...
-
- if (ourCallBack == NULL) {
- ourCallBack = NewServerEventHandlerProc (ServerEventHandler);
- } // if
- eventQueueEntry->queueEntry.callBack = ourCallBack;
-
- // Initially, clear all flags so we won't see any events...
-
- eventQueueEntry->queueEntry.serverEventMask = 0;
- eventQueueEntry->queueEntry.afpCommandMask[0] = 0;
- eventQueueEntry->queueEntry.afpCommandMask[1] = 0;
- eventQueueEntry->queueEntry.serverControlMask = 0;
-
- // Caller gave us a block of OurServerEventRecords, which we should now push on the
- // free queue...
-
- eventQueueEntry->freeQ = emptyQueueInit;
- eventQueueEntry->usedQ = emptyQueueInit;
-
- while (numEventRecords > 0) {
- numEventRecords -= 1;
- Enqueue ((QElemPtr) &toQueue[numEventRecords], &eventQueueEntry->freeQ);
- } // while
-
- return err;
-
- } // InitServerEventQueueData
-
- // Sample 5c:
- // ServerEventHandler receives events and puts them on a queue for the application to
- // process later...
- pascal void
- ServerEventHandler (OurServerEventQEntry* mainEntry, ExtendedServerEventRecord* event) {
-
- OSErr err = noErr;
- OurServerEventRecord* newEntry;
-
- // If there is free space in the queue, get it; if there is not, purge the oldest
- // item in the used queue (you may want to behave differently, such as purging
- // items that are of less interest, etc.)
-
- newEntry = (OurServerEventRecord*) mainEntry->freeQ.qHead;
- if (newEntry != NULL) {
- err = Dequeue ((QElemPtr) newEntry, &mainEntry->freeQ);
- } else {
- newEntry = (OurServerEventRecord*) mainEntry->usedQ.qHead;
- err = Dequeue ((QElemPtr) newEntry, &mainEntry->usedQ);
- } // if
-
- // Now we have an entry; stuff the event record into it, and requeue it on the
- // "used" side...
-
- if (err == noErr) {
- newEntry->eventRec = *event;
- Enqueue ((QElemPtr) newEntry, &mainEntry->usedQ);
- } // if
-
- } // ServerEventHandler
-
- // Sample 5d;
- // SetEventFlag determines what server _events_ a handler will receive...
- void
- SetEventFlag (OurServerEventQEntry* mainEntry, UInt32 whichEvent, Boolean onOff) {
-
- UInt32 maskValue = 0x1 << whichEvent;
-
- if (onOff) {
- mainEntry->queueEntry.serverEventMask |= maskValue;
- } else {
- mainEntry->queueEntry.serverEventMask &= ~maskValue;
- } // if
-
- } // SetEventFlag
-
- // Sample 5e;
- // SetControlFlag determines what server _control_ calls a handler will receive...
- void
- SetControlFlag (OurServerEventQEntry* mainEntry, UInt32 whichEvent, Boolean onOff) {
-
- UInt32 maskValue = 0x1 << whichEvent;
-
- if (onOff) {
- mainEntry->queueEntry.serverControlMask |= maskValue;
- } else {
- mainEntry->queueEntry.serverControlMask &= ~maskValue;
- } // if
-
- } // SetControlFlag
-
- // Sample 5f;
- // SetAFPFlag determines what AFP calls a handler will receive (only 1->64 are
- // interceptable)...
- void
- SetAFPFlag (OurServerEventQEntry* mainEntry, UInt32 whichEvent, Boolean inDo,
- Boolean inReply, Boolean onOff) {
-
- UInt32 maskValue0 = 0;
- UInt32 maskValue1 = 0;
-
- // Special case of AddIcon gets remapped to bit 0...
- if (whichEvent == afpAddIcon) {
- whichEvent = 0;
- } // if
-
- if (whichEvent >= 32) {
- maskValue0 = 1 << (whichEvent % 32);
- } else {
- maskValue1 = 1 << whichEvent;
- } // if
-
- if (onOff) {
- mainEntry->queueEntry.afpCommandMask[0] |= maskValue0;
- mainEntry->queueEntry.afpCommandMask[1] |= maskValue1;
- } else {
- mainEntry->queueEntry.afpCommandMask[0] &= ~maskValue0;
- mainEntry->queueEntry.afpCommandMask[1] &= ~maskValue1;
- } // if
-
- // We need to set the appropriate Event flag(s) so this actually gets called...
-
- if (inDo) {
- SetEventFlag (mainEntry, kSCStartAFPRequestEvt, onOff);
- } // if
- if (inReply) {
- SetEventFlag (mainEntry, kSCSendAFPResponseEvt, onOff);
- } // if
-
- } // SetAFPFlag
-
- // Sample 5g:
- // ProcessQueuedEvents goes through the events that have queued up, and does something
- // with them (in our case, simply beeps)...
- void
- ProcessQueuedEvents (OurServerEventQEntry* mainEntry) {
-
- OSErr err = noErr;
- OurServerEventRecord* nextEntry;
-
- nextEntry = (OurServerEventRecord*) mainEntry->usedQ.qHead;
- if (nextEntry != NULL) {
- err = Dequeue ((QElemPtr) nextEntry, &mainEntry->usedQ);
- if (err == noErr) {
- SysBeep (0);
- Enqueue ((QElemPtr) nextEntry, &mainEntry->freeQ);
- } // if
- } // if
-
- } // ProcessQueuedEvents
-
- // ---------------------------------------------------------------------------------------
-
- // Test code to see that it all works...
-
- #define kMaxNumSharePoints 10
- #define kMaxNumQueueEvents 100
- #define kNumberOfSecondsToIntercept 60
-
- int main(void)
- {
-
- SInt16 vRefNum[kMaxNumSharePoints];
- SInt32 dirID[kMaxNumSharePoints];
- SInt16 logins[kMaxNumSharePoints];
- OurServerEventQEntry ourEntry;
- OurServerEventRecord queuedEvents[kMaxNumQueueEvents];
- UInt32 start;
-
- printf ("Begin Test\n");
-
- // Sample 1 test...
-
- StartStopServer (true, 1);
-
- // Sample 2 test...
-
- GetSharedVolumeInfo (vRefNum, dirID, logins, kMaxNumSharePoints);
-
- // Sample 3 test...
-
- SendGreetingToAll ();
-
- // Sample 4, 5 test...
-
- InitServerEventQueueData (&ourEntry, queuedEvents, kMaxNumQueueEvents);
- SetEventFlag (&ourEntry, kSCVolumePrepEvt, true);
- SetControlFlag (&ourEntry, kSCDisconnect, true);
- SetAFPFlag (&ourEntry, afpAddIcon, true, false, true);
- SetAFPFlag (&ourEntry, afpAddAPPL, true, true, true);
- SetAFPFlag (&ourEntry, afpDelete, true, true, true);
-
- InstallOrRemoveEventHandler (&ourEntry.queueEntry, true);
-
- start = LMGetTicks ();
- while (start + kNumberOfSecondsToIntercept * 60 > LMGetTicks ()) {
- if (LMGetTicks () % 60 == 0) printf ("Tick %d\n", LMGetTicks ());
- ProcessQueuedEvents (&ourEntry);
- } // while
-
-
- InstallOrRemoveEventHandler (&ourEntry.queueEntry, false);
-
- return 0;
- }
-
-